﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Identity.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using System.Data;
using T.Personnel.Domain;
using T.Personnel.Domain.Dto;
using T.Personnel.Repository.Interface;
using System.Threading.Tasks;
using T.ApprovalRecord;

namespace T.Personnel.Repository.Impl
{
    public class BaseManageRepository : BaseRepository<Manage>, IManageRepository
    {
        private readonly EFDbcontext db;
        private readonly IRegisterRepository registerRepository;
        public BaseManageRepository(EFDbcontext eFDbcontext, IRegisterRepository registerRepository, EFDbcontext db) : base(eFDbcontext)
        {
            this.registerRepository = registerRepository;
            this.db = db;
        }

        public async Task<int> AddEntryAsync(Manage manage)
        {
            // 开始事务
            using (var transaction = await db.Database.BeginTransactionAsync())
            {
                try
                {
                    // 获取 StaffId 对应的记录
                    var allor = await registerRepository.GetAsync(x => x.Id == manage.StaffId);
                    if (allor == null)
                    {
                        throw new ArgumentException("Staff not found.");
                    }

                    if (allor.Hiredate != manage.Hiredate)
                    {
                        // 更新员工的 Hiredate
                        allor.Hiredate = manage.Hiredate;
                        await registerRepository.UpdAsync(allor);
                    }

                    // 设置 manage 类型
                    manage.ManageType = 1;

                    // 将新的 manage 记录插入数据库
                    int result = await base.AddAsync(manage);

                    // 提交事务
                    await transaction.CommitAsync();  // 异步提交事务

                    return result;
                }
                catch (Exception ex)
                {
                    // 事务回滚
                    await transaction.RollbackAsync();  // 异步回滚事务

                    // 可以在这里记录日志，方便调试
                    // logService.LogError(ex);

                    // 抛出异常到上层
                    throw new ApplicationException("Error while adding entry.", ex);
                }
            }
        }

        public async Task<int> AddFullAsync(Manage manage)
        {
            // 开始事务
            using (var transaction = await db.Database.BeginTransactionAsync())
            {
                try
                {
                    var allor = await registerRepository.GetAsync(x => x.Id == manage.StaffId);
                    allor.State = "待转正";
                    await registerRepository.UpdAsync(allor);
                    // 设置 manage 类型
                    manage.ManageType = 3;

                    // 将新的 manage 记录插入数据库
                    int result = await base.AddAsync(manage);

                    // 提交事务
                    await transaction.CommitAsync();  // 异步提交事务

                    return result;
                }
                catch (Exception ex)
                {
                    // 事务回滚
                    await transaction.RollbackAsync();  // 异步回滚事务

                    // 可以在这里记录日志，方便调试
                    // logService.LogError(ex);

                    // 抛出异常到上层
                    throw new ApplicationException("Error while adding entry.", ex);
                }
            }                
        }

        public async Task<int> AddResignationAsync(Manage manage)
        {
            // 开始事务
            using (var transaction = await db.Database.BeginTransactionAsync())
            {
                try
                {
                    var allor = await registerRepository.GetAsync(x => x.Id == manage.StaffId);
                    allor.State = "待离职";
                    await registerRepository.UpdAsync(allor);
                    // 设置 manage 类型
                    manage.ManageType = 2;

                    // 将新的 manage 记录插入数据库
                    int result = await base.AddAsync(manage);

                    // 提交事务
                    await transaction.CommitAsync();  // 异步提交事务

                    return result;
                }
                catch (Exception ex)
                {
                    // 事务回滚
                    await transaction.RollbackAsync();  // 异步回滚事务

                    // 可以在这里记录日志，方便调试
                    // logService.LogError(ex);

                    // 抛出异常到上层
                    throw new ApplicationException("Error while adding entry.", ex);
                }
            }                
        }

        public async Task<int> DelEntryAsync(int id,string name)
        {
            var allor = await base.GetAsync(id);
            allor.DeletedBy = name;
            allor.DeletedDate = DateTime.Now;
            allor.IsDeleted = true;
            return await base.UpdAsync(allor);
        }

        public async Task<int> DelFullAsync(int id,string name)
        {
            var allor = await base.GetAsync(id);
            allor.DeletedBy = name;
            allor.DeletedDate = DateTime.Now;
            allor.IsDeleted = true;
            return await base.UpdAsync(allor);
        }

        public async Task<int> DelResignationAsync(int id,string name)
        {
            var allor = await base.GetAsync(id);
            allor.DeletedBy = name;
            allor.DeletedDate = DateTime.Now;
            allor.IsDeleted = true;
            return await base.UpdAsync(allor);
        }

        public async Task<List<Manage>> GetAllEntryAsync()
        {
            var gather = await base.GetListAsync(x => x.IsDeleted == false && x.ManageType == 1);
            return gather.ToList();
        }

        public async Task<List<Manage>> GetAllResignationAsync()
        {
            var gather = await base.GetListAsync(x => x.IsDeleted == false && x.ManageType == 2);
            return gather.ToList();

        }

        public async Task<Result<Manage>> GetEntryAsync(string? Name, int? DepartmentId, int? PositionId, DateTime? Hiredate, DateTime? CreatedDate, string? AppStatus, int PageIndex, int PageSize)
        {
            var gather = await base.GetListAsync(x => x.IsDeleted == false && x.ManageType == 1);
            if (Name != null)
            {
                gather = gather.Where(x=>x.StaffName.Contains(Name));
            }
            if(DepartmentId != null)
            {
                gather = gather.Where(x => x.DepartmentId == DepartmentId);
            }
            if(PositionId != null)
            {
                gather = gather.Where(x => x.PositionId == PositionId);
            }
            if(Hiredate != null)
            {
                gather = gather.Where(x => x.Hiredate.Date == Hiredate.Value.Date);
            }
            if (CreatedDate != null)
            {
                gather = gather.Where(x => x.CreatedDate.HasValue && x.CreatedDate.Value.Date == CreatedDate.Value.Date);
            }
            if (AppStatus != null)
            {
                gather = gather.Where(x => x.AppStatus == AppStatus);
            }

            var totalCount = gather.Count();
            var totalPage = (int)Math.Ceiling(totalCount * 1.0 / PageSize);
            var list = gather.Skip((PageIndex - 1) * PageSize).Take(PageSize).ToList();
            Result<Manage> result = new Result<Manage>();
            result.TotalCount = totalCount;
            result.TotalPage = totalPage;
            result.Data = list;
            return result;
        }

        public async Task<Result<Manage>> GetEntrysAsync(string? Name, int? DepartmentId, int? PositionId, DateTime? Hiredate, DateTime? CreatedDate, string? AppStatus, int PageIndex, int PageSize, int? Stat)
        {
            var gather = await base.GetListAsync(x => x.IsDeleted == false && x.ManageType == 1&&x.AppStatus!="待提交");
            if (Name != null)
            {
                gather = gather.Where(x => x.StaffName.Contains(Name));
            }
            if (DepartmentId != null)
            {
                gather = gather.Where(x => x.DepartmentId == DepartmentId);
            }
            if (PositionId != null)
            {
                gather = gather.Where(x => x.PositionId == PositionId);
            }
            if (Hiredate != null)
            {
                gather = gather.Where(x => x.Hiredate.Date == Hiredate.Value.Date);
            }
            if (CreatedDate != null)
            {
                gather = gather.Where(x => x.CreatedDate.HasValue && x.CreatedDate.Value.Date == CreatedDate.Value.Date);
            }
            if (AppStatus != null)
            {
                gather = gather.Where(x => x.AppStatus == AppStatus);
            }
            if (Stat != null)
            {
                if (Stat == 1)
                {
                    gather = gather.Where(x => x.AppStatus == "待审批");
                }
                else if (Stat == 2)
                {
                    gather = gather.Where(x => x.AppStatus == "已同意" || x.AppStatus == "已拒绝");
                }
            }

            var totalCount = gather.Count();
            var totalPage = (int)Math.Ceiling(totalCount * 1.0 / PageSize);
            var list = gather.Skip((PageIndex - 1) * PageSize).Take(PageSize).ToList();
            Result<Manage> result = new Result<Manage>();
            result.TotalCount = totalCount;
            result.TotalPage = totalPage;
            result.Data = list;
            return result;
        }

        public async Task<Manage> GetEntryAsync(int id)
        {
            return await base.GetAsync(x => x.Id == id && x.ManageType == 1);
        }

        public async Task<Result<Manage>> GetFullAsync(string? Name, int? DepartmentId, int? PositionId, DateTime? Hiredate, DateTime? ApplicationDate, string? AppStatus, int PageIndex, int PageSize)
        {
            var gather = await base.GetListAsync(x => x.IsDeleted == false && x.ManageType == 3);
            if (Name != null)
            {
                gather = gather.Where(x => x.StaffName.Contains(Name));
            }
            if (DepartmentId != null)
            {
                gather = gather.Where(x => x.DepartmentId == DepartmentId);
            }
            if (PositionId != null)
            {
                gather = gather.Where(x => x.PositionId == PositionId);
            }
            if (Hiredate != null)
            {
                gather = gather.Where(x => x.Hiredate.Date == Hiredate.Value.Date);
            }
            if (ApplicationDate != null)
            {
                gather = gather.Where(x => x.ApplicationDate.HasValue && x.ApplicationDate.Value.Date == ApplicationDate.Value.Date);
            }
            if (AppStatus != null)
            {
                gather = gather.Where(x => x.AppStatus == AppStatus);
            }

            var totalCount = gather.Count();
            var totalPage = (int)Math.Ceiling(totalCount * 1.0 / PageSize);
            var list = gather.Skip((PageIndex - 1) * PageSize).Take(PageSize).ToList();
            Result<Manage> result = new Result<Manage>();
            result.TotalCount = totalCount;
            result.TotalPage = totalPage;
            result.Data = list;
            return result;
        }

        public async Task<Result<Manage>> GetFullsAsync(string? Name, int? DepartmentId, int? PositionId, DateTime? Hiredate, DateTime? ApplicationDate, string? AppStatus, int PageIndex, int PageSize, int? Stat)
        {
            var gather = await base.GetListAsync(x => x.IsDeleted == false && x.ManageType == 3&&x.AppStatus!="待提交");
            if (Name != null)
            {
                gather = gather.Where(x => x.StaffName.Contains(Name));
            }
            if (DepartmentId != null)
            {
                gather = gather.Where(x => x.DepartmentId == DepartmentId);
            }
            if (PositionId != null)
            {
                gather = gather.Where(x => x.PositionId == PositionId);
            }
            if (Hiredate != null)
            {
                gather = gather.Where(x => x.Hiredate.Date == Hiredate.Value.Date);
            }
            if (ApplicationDate != null)
            {
                gather = gather.Where(x => x.ApplicationDate.HasValue && x.ApplicationDate.Value.Date == ApplicationDate.Value.Date);
            }
            if (AppStatus != null)
            {
                gather = gather.Where(x => x.AppStatus == AppStatus);
            }
            if (Stat != null)
            {
                if (Stat == 1)
                {
                    gather = gather.Where(x => x.AppStatus == "待审批");
                }
                else if (Stat == 2)
                {
                    gather = gather.Where(x => x.AppStatus == "已同意" || x.AppStatus == "已拒绝");
                }
            }

            var totalCount = gather.Count();
            var totalPage = (int)Math.Ceiling(totalCount * 1.0 / PageSize);
            var list = gather.Skip((PageIndex - 1) * PageSize).Take(PageSize).ToList();
            Result<Manage> result = new Result<Manage>();
            result.TotalCount = totalCount;
            result.TotalPage = totalPage;
            result.Data = list;
            return result;
        }

        public async Task<Manage> GetFullAsync(int id)
        {
            return await base.GetAsync(x => x.Id == id && x.ManageType == 3);
        }

        public async Task<Result<Manage>> GetResignationAsync(string? Name, int? DepartmentId, int? PositionId, DateTime? Hiredate, DateTime? LastDay, string? AppStatus, int PageIndex, int PageSize)
        {
            var gather = await base.GetListAsync(x => x.IsDeleted == false && x.ManageType == 2);
            if (Name != null)
            {
                gather = gather.Where(x => x.StaffName.Contains(Name));
            }
            if (DepartmentId != null)
            {
                gather = gather.Where(x => x.DepartmentId == DepartmentId);
            }
            if (PositionId != null)
            {
                gather = gather.Where(x => x.PositionId == PositionId);
            }
            if (Hiredate != null)
            {
                gather = gather.Where(x => x.Hiredate.Date == Hiredate.Value.Date);
            }
            if (LastDay != null)
            {
                gather = gather.Where(x => x.LastDay.HasValue && x.LastDay.Value.Date == LastDay.Value.Date);
            }
            if (AppStatus != null)
            {
                gather = gather.Where(x => x.AppStatus == AppStatus);
            }

            var totalCount = gather.Count();
            var totalPage = (int)Math.Ceiling(totalCount * 1.0 / PageSize);
            var list = gather.Skip((PageIndex - 1) * PageSize).Take(PageSize).ToList();
            Result<Manage> result = new Result<Manage>();
            result.TotalCount = totalCount;
            result.TotalPage = totalPage;
            result.Data = list;
            return result;
        }

        public async Task<Result<Manage>> GetResignationsAsync(string? Name, int? DepartmentId, int? PositionId, DateTime? Hiredate, DateTime? LastDay, string? AppStatus, int PageIndex, int PageSize, int? Stat)
        {
            var gather = await base.GetListAsync(x => x.IsDeleted == false && x.ManageType == 2 && x.AppStatus != "待提交");
            if (Name != null)
            {
                gather = gather.Where(x => x.StaffName.Contains(Name));
            }
            if (DepartmentId != null)
            {
                gather = gather.Where(x => x.DepartmentId == DepartmentId);
            }
            if (PositionId != null)
            {
                gather = gather.Where(x => x.PositionId == PositionId);
            }
            if (Hiredate != null)
            {
                gather = gather.Where(x => x.Hiredate.Date == Hiredate.Value.Date);
            }
            if (LastDay != null)
            {
                gather = gather.Where(x => x.LastDay.HasValue && x.LastDay.Value.Date == LastDay.Value.Date);
            }
            if (AppStatus != null)
            {
                gather = gather.Where(x => x.AppStatus == AppStatus);
            }
            if (Stat != null)
            {
                if (Stat == 1)
                {
                    gather = gather.Where(x => x.AppStatus == "待审批");
                }
                else if (Stat == 2)
                {
                    gather = gather.Where(x => x.AppStatus == "已同意" || x.AppStatus == "已拒绝");
                }
            }

            var totalCount = gather.Count();
            var totalPage = (int)Math.Ceiling(totalCount * 1.0 / PageSize);
            var list = gather.Skip((PageIndex - 1) * PageSize).Take(PageSize).ToList();
            Result<Manage> result = new Result<Manage>();
            result.TotalCount = totalCount;
            result.TotalPage = totalPage;
            result.Data = list;
            return result;
        }

        public async Task<Manage> GetResignationAsync(int id)
        {
            return await base.GetAsync(x => x.Id == id && x.ManageType == 2);
        }

        public async Task<int> UpdEntryAsync(Manage manage)
        {
            using (var transaction = await db.Database.BeginTransactionAsync())
            {
                try
                {
                    // 获取 StaffId 对应的记录
                    var allor = await registerRepository.GetAsync(x => x.Id == manage.StaffId);
                    if (allor == null)
                    {
                        throw new ArgumentException("Staff not found.");
                    }

                    if (allor.Hiredate != manage.Hiredate)
                    {
                        // 更新员工的 Hiredate
                        allor.Hiredate = manage.Hiredate;
                        await registerRepository.UpdAsync(allor);
                    }

                    // 设置 manage 类型
                    manage.ManageType = 1;

                    // 将新的 manage 记录更新数据库
                    int result = await base.UpdAsync(manage);

                    // 提交事务
                    await transaction.CommitAsync();  // 异步提交事务

                    return result;
                }
                catch (Exception ex)
                {
                    // 事务回滚
                    await transaction.RollbackAsync();  // 异步回滚事务

                    // 可以在这里记录日志，方便调试
                    // logService.LogError(ex);

                    // 抛出异常到上层
                    throw new ApplicationException("Error while adding entry.", ex);
                }
            }
        }

        public async Task<int> UpdFullAsync(Manage manage)
        {
            try
            {
                // 设置 manage 类型
                manage.ManageType = 3;

                // 将新的 manage 记录更新数据库
                int result = await base.UpdAsync(manage);

                return result;
            }
            catch (Exception ex)
            {
                // 可以在这里记录日志，方便调试
                // logService.LogError(ex);

                // 抛出异常到上层
                throw new ApplicationException("Error while adding entry.", ex);
            }
        }

        public async Task<int> UpdResignationAsync(Manage manage)
        {
            try
            {
                // 设置 manage 类型
                manage.ManageType = 2;

                // 将新的 manage 记录更新数据库
                int result = await base.UpdAsync(manage);

                return result;
            }
            catch (Exception ex)
            {
                // 可以在这里记录日志，方便调试
                // logService.LogError(ex);

                // 抛出异常到上层
                throw new ApplicationException("Error while adding entry.", ex);
            }
        }
    }
}
